//
//  QCAboutViewController.swift
//  爱汽车
//
//  Created by liujianlong on 2023/8/23.
//

import UIKit
import TCCKit
import CoreBluetooth

private enum CellType{
    case on_off(_ model:CellModify)
    case text(_ model:CellModify)
    case update(_ model:CellModify)
    case active
}
private struct CellModify{
    var title : String
    var tag : String?
    var subTitle : String?
    var content : String?
    var bghex : String?
    var ison : Bool?
    var ota : OTAModel?
    var service:String?
}
enum OTAStatus{
    case normal
    case updating
    case done
}
class QCAboutViewController: QCViewController {
    private var array = [[CellType]]()
    private var isActive = false
    var otaStatus = OTAStatus.normal
    var btn_select_index : IndexPath!
    var current_OTA_Model : OTAModel!
    ///激活码
    private var activeCode = ""
    private var mac = ""
    private var didDownload = false
    var bin_array = Array<Any>()
    var bin_index = 0
    ///客户MCU，进入BOOT
    var boot = false
    ///客户MCU，进入型号匹配
    var match = false
    ///上传imei
    var didsave = false
    override func viewDidLoad() {
        super.viewDidLoad()
        initUI()
    }
    
    override func initUI() {
        title = LS("关于")
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(QCSettingCell.nib(), forCellReuseIdentifier: QCSettingCell.ID())
        tableView.register(QCActiveCell.nib(), forCellReuseIdentifier: QCActiveCell.ID())
        tableView.register(QCAboutCell.nib(), forCellReuseIdentifier: QCAboutCell.ID())
        tableView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        CCHud.stop()
    }
    
    @objc override func initData() {
        super.initData()
        var firmwareVersion = ""
        if BLE.connectedPeripherals.count > 0 , let per = BLE.connectedPeripherals.first,APP.mcuArray.count > 0, let mcu = APP.mcuArray.first{
            firmwareVersion = mcu.versionStr.count < 2 ? "" : mcu.versionStr[0...mcu.versionStr.count-2]
        }
        
        let modify1 = CellModify(title: "系统升级", ison: false)
        let modify2 = CellModify(title: "TouchPad", content: firmwareVersion, bghex:"#F28D27", service: TouchPad_service)
        var modify3 = CellModify(title: "Bluetooth", tag: "02",content: firmwareVersion,bghex: "#F28D27")
        var modify4 = CellModify(title: "TouchPad", tag: "03",bghex: "#F28D27")
        var modify5 = CellModify(title: "MCU", tag: "04",bghex: "#F28D27")
        var modify6 = CellModify(title: "Watch", tag: "02",content: firmwareVersion, bghex: "#2BA6F7",service: Watch_service)
        let modify7 = CellModify(title: "APP", subTitle:APP.appModel.ota != "" ? "有版本更新" : "已是最新", content: APP.appModel.version,bghex: "#F28D27")
        let modify8 = CellModify(title: "激活设备", ison: false)
        
        var array1 : [CellType] = [array.count > 0 ? array[0][0] : .on_off(modify1),
                                   .update(modify7)]
        var array2 : [CellType] = [array.count > 0 ? array[1][0] : .on_off(modify8),
                                   .active]
        
        ///区分连接的是旋钮还是手环
        ///区分，如果连接的旋钮，区分连接旋钮的哪几个MCU
        if BLE.connectedPeripherals.count > 0, let per = BLE.connectedPeripherals.first, let services = per.services {
            mac = per.mac
            if services.contains(where: {$0.uuid.uuidString == modify2.service}){
                //array1.append(.text(modify2))
                judg(&modify3)///如果连接了编号=02的MCU，则连接了主蓝牙MCU
                judg(&modify4)///如果连接了编号=03的MCU，则连接了显示屏MCU
                judg(&modify5)///如果连接了编号=04的MCU，则连接了客户的其他MCU
            }else if services.contains(where: {$0.uuid.uuidString == modify6.service}){
                judg(&modify6)
            }
        }
        
        func judg(_ modify:inout CellModify){
            if APP.mcuArray.contains(where: {$0.tag == modify.tag}) == false{return}
            let mcu = APP.mcuArray.filter{$0.tag ==  modify.tag}.first
            let update = APP.otaArray.contains(where: {$0.tag == modify.tag})
            modify.subTitle = update ? "有版本更新" : "已是最新"
            modify.content = mcu?.versionStr
            modify.ota = update ? APP.otaArray.filter{$0.tag == modify.tag}.first : nil
            modify.bghex = update ? "#F28D27" : "#2BA6F7"
            array1.append(.update(modify))
        }
        let temp =  array1.remove(at: 1)
        array1.insert(temp, at: array1.count)
        array = [array1,array2]
        tableView.reloadData()
    }
    
    override func backBtnAction() {
        if otaStatus == .updating{
            CCHud.stop()
            alert("注意","升级还未完成，请稍后再退出",nil,{[weak self] in
                self?.navigationController?.popViewController(animated: true)
            })
            return
        }
        super.backBtnAction()
    }
    
    override var base_info: [UInt8]{
        didSet{
            let data = [UInt8](base_info[AI_index..<base_info.count])
            let active = Int(data[37]) == 1
            if active == isActive{ return}
            isActive = active
            tableView.reloadData()
        }
    }
    
    override var bytes: [UInt8]{
        didSet{
            let ack = bytes[7]
            let data = [UInt8](bytes[AI_index..<bytes.count])
            OTA_bytes = bytes
            switch ack{
            case UInt8(AIQC.active.ack):
                isActive = Int(data[0]) == 1
                let text = isActive ? "激活成功" : "激活失败"
                CCHud.start(LS(text), stopTime: 1.5)
                if isActive {//获取序列号
                    BLEData.appSetDataToPer(AIQC.IMEI.cmd, "00").write
                    tableView.reloadData()
                }
            case UInt8(AIQC.unActive.ack):
                print("解除激活")
            case UInt8(AIQC.IMEI.ack):
                //            case UInt8(AIQC.IMEI_MCU.ack):
                ///获取芯片序列号，告诉后台
                if data.count < 16 {return}
                let imei = data[0..<16].map{UInt8($0)}
                save(imei)
            default:
                break
            }
        }
    }
    
    override var connectStatus: BLEStatus{
        didSet{
            switch connectStatus{
            case .DFU:
                print("==========> \(BLE.connectedPeripherals)")
                if didDownload == false{ return}
                if BLE.connectedPeripherals.count <= 0{return}
                if OTAName.contains(BLE.connectedPeripherals.first?.name ?? "") == false{return}
                guard let array = APP.otaArray.filter({$0.tag == "02"}) as? [OTAModel], array.count > 0, let model = array.first else{return}
                current_OTA_Model = model
                OTA()
            case .normal:
                APP.otaArray.removeFirst()
                search()
            case .connectedSucces:
                otaStatus = .done
                boot = false
                match = false
            default:
                break
            }
        }
    }
    
    func search(){
        let filterProductName = productName()
        BLE.scanWithOther = { peripheral in
            let product = String(format: "%.2X%.2X", peripheral.advertData[1],peripheral.advertData[0])
            return filterProductName.contains(product) || OTAName.contains(peripheral.name ?? "")
        }
        BLE.scanWithServices = [TouchPad_service, Watch_service, Nordic_OTA_service]
        BLE.startScan { [weak self] array in
            MyPrint("=================搜索了\(BLE.status)")
            if BLE.connectedPeripherals.count > 0{return}
//            if BLE.status == .DFU{
            MyPrint("==========\(array)   == \(self!.mac)")
//                if let result = array.filter({OTAName.contains($0.name ?? "")}) as? [CBPeripheral], result.count > 0{
                    if let temp = self?.mac.components(separatedBy: ":"), temp.count > 0{
                        let num = temp.last?.toDecimal() ?? 0 /// Mac地址最后一位的十进制值，nordic的ota模式，
                        for per in array{
                            let temp2 = per.mac.components(separatedBy: ":")
                            if temp2.count <= 0{break}
                            let num2 = temp2.last?.toDecimal() ?? 0
                            if (BLE.status == .DFU && num2 == num + 1) || (BLE.status == .normal && num2 == num - 1){
                                MyPrint("======>   per 充连。=。\(per)    mac = \(per.mac)。  self.mac == \(self!.mac) ")
                                BLE.connect(per)
                                return
                            }
//                        }
//                    }
                }
            }
        }
    }
    
    
    /// 按钮事件
    func action(_ btnTitle:String, index:IndexPath?, value:String){
        if btnTitle == LS("激活") || btnTitle == LS("已激活"){
            if value.count <= 0{return}
            activeCode = value
            let ascii = value.ascii.map{String(format:"%2X", $0)}.joined()
            CCHud.start(isActive ? LS("冻结中..."):LS("激活中..."), stopTime: 1.5)
            BLEData.appSetDataToPer(isActive ? AIQC.unActive.cmd : AIQC.active.cmd, ascii).write
            //            BLEData.appSetDataToPer(AIQC.unActive.cmd, ascii).write
            return
        }
        
        if case let .update(modify) = array[index!.section][index!.row]{
            switch (modify.title, modify.subTitle){
            case ("APP","已是最新"):
                APP.checkAPPUpdate()
            case ("APP","有版本更新"):
                guard let url = URL(string: APP.appModel.ota) else {return}
                UIApplication.shared.open(url, options:[:], completionHandler:nil)
            case (_,"已是最新"):
                if BLE.status == .DFU{return}
                btnState(text:"检查中...", index: index!)
                APP.checkOTA(false)
            case (_,"有版本更新"):
                if otaStatus == .updating{return}
                otaStatus = .updating
                btnState(text:"正在下载...", index: index!)
                current_OTA_Model = modify.ota
                downdload()
            default:
                break
            }
        }
    }
    
    ///更改按钮状体啊
    func btnState(text:String, index:IndexPath){
        btn_select_index = index
        if case var .update(modify) = array[index.section][index.row]{
            if text == "已是最新"{
                otaStatus = .normal
                modify.bghex =  "#F28D27"
            }
            modify.subTitle = text
            modify.bghex = "#2BA6F7"
            array[index.section][index.row] = .update(modify)
            tableView.reloadData()
        }
    }
    
    ///保存激活序列号
    private func save(_ imei:Array<UInt8>){
        if activeCode == "" || didsave == true{return}
        let string = String(bytes: imei, encoding: .ascii) ?? ""
        let dict = ["cdkey":activeCode,"productSn":string];
        NetworkTool.request(.reactive(dict)) {[weak self] response in
            self?.didsave = true
        }
    }
    
    /// 把需要升级的文件下载到本地
    private func downdload(_ i:Int = 0){
        let totalSize = APP.otaArray.map{$0.fileSize}.reduce(0, {$0+$1})
        print("准备下载 下载地址是 == \(current_OTA_Model.ota) \n size = \(totalSize)")
        NetworkTool.request(.download(current_OTA_Model.ota,current_OTA_Model.fileName)) {[weak self] json in
            self?.current_OTA_Model.localPath = json["fileURL"].stringValue
            APP.otaArray[i] = self?.current_OTA_Model ?? OTAModel()
            self?.localZIP()
            //self?.downdload(i+1)
            print("======下载\(json)")
        }
    }
    
    /// 从本地加载出数据
    private func localZIP(){
        var url = current_OTA_Model.localPath
        url = url[7...url.count]///这里特别注意，因为下载到本地，地址包含file:///，如果不去掉，下面判定本地是否存在不成功，所以这里必须去掉
        if FileManager.default.fileExists(atPath:url){
            guard let data = try? Data(contentsOf: URL(string:current_OTA_Model.localPath)!) else{ return}
            current_OTA_Model.data = data
            print("下载完成")
        }else{
            print("没有路径")
        }
        didDownload = true
        OTA()
    }
    
    ///各种芯片，各种用途，各种升级方式，在这里分开
    private func OTA(){
        btnState(text: "准备更新", index: btn_select_index)
        print("==== name ,\(current_OTA_Model.binCode),  size \(current_OTA_Model.data.count)")
        let hexCode = current_OTA_Model.code[2...current_OTA_Model.code.count-1]
        switch (current_OTA_Model.platform,hexCode){
        case ("nordic","FFFFF9"):///nordic官方, (官方文件，走官方ota)
            Nordic_OTA()
        case ("fr8000x","FFFFF9"):///富丽坤官方, (官方文件，走官方ota)
            FRQ_OTA()
        case ("Unlimited_platform","FFFFFE"):///其他没有平台的 mcu，以普通bin文件传送方式, (IAP类升级文件，非强制性)
            BIN_OTA()
        case ("Customer_platform","FFFFFD"):///客户主控制板, (走客户协议，以分包形式)
            XLBIN_OTA()
        case (_,"FFFFFF"):///表盘文件
            break
        case (_,"FFFFFC"):///程序文件
            break
        case (_,"FFFFFB"):///UI文件
            break
        case (_,"FFFFFA"):///开机logo文件
            break
        default:
            break
        }
    }
}

//MARK: - UITableViewDataSource
extension QCAboutViewController : UITableViewDataSource
{
    func numberOfSections(in tableView: UITableView) -> Int {
        return array.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if case let .on_off(modify) = array[section][0]{
            return modify.ison ?? false ? array[section].count : 1
        }
        return 0
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch array[indexPath.section][indexPath.row]{
        case let .on_off(modify):
            let cell = tableView.dequeueReusableCell(withIdentifier: QCSettingCell.ID()) as! QCSettingCell
            cell.title.text = LS(modify.title)
            cell.type = modify.ison ?? false ? .subImg("arrow_up") : .subImg("arrow_down")
            return cell
        case let .text(modify):
            let cell = tableView.dequeueReusableCell(withIdentifier: QCSettingCell.ID()) as! QCSettingCell
            cell.title.text = LS(modify.title)
            cell.type = .onlyText(modify.content ?? "")
            cell.contentView.bgHexColor = "#161718"
            return cell
        case let.update(modify):
            let cell = tableView.dequeueReusableCell(withIdentifier: QCAboutCell.ID()) as! QCAboutCell
            if  modify.subTitle == "已是最新" {
                cell.btnWidth.constant  = -16
            }
            cell.btn.isHidden = modify.subTitle == "已是最新"
            cell.title.text = LS(modify.title)
            cell.subTitlte.text = LS(modify.content ?? "")
            cell.btn.setTitle(modify.subTitle == "已是最新" ? "" : LS(modify.subTitle ?? ""), for: .normal)
            cell.btn.bgHexColor = modify.bghex ?? ""
            cell.block = {[weak self] in
                self?.action(modify.subTitle ?? "", index: indexPath, value:"")
            }
            return cell
        case .active:
            let cell = tableView.dequeueReusableCell(withIdentifier: QCActiveCell.ID()) as! QCActiveCell
            cell.btn.isEnabled = !isActive
            cell.btn.bgHexColor = !isActive ? "#FF4B00" : "#999999"
            cell.btn.setTitle(isActive ?  LS("已激活") : LS("激活"), for: .normal)
            //                        cell.btn.setTitle(isActive ?  "冻结激活" : "激活", for: .normal)
            cell.block = {[weak self]  text in
                self?.action(self?.isActive ?? false ?  LS("已激活") : LS("激活"), index: nil ,value: text)
                //                self?.action("激活", index: nil ,value: text)
                
            }
            return cell
        }
    }
}
//MARK: - UITableViewDelegate
extension QCAboutViewController : UITableViewDelegate
{
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if case var .on_off(modify) = array[indexPath.section][indexPath.row]{
            modify.ison = !(modify.ison ?? false)
            array[indexPath.section][indexPath.row] = .on_off(modify)
            tableView.reloadData()
        }
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 0
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        if case let .on_off(modify) = array[0][0]{
            return modify.ison ?? false ? 0 : 3
        }
        return 0
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return nil
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        if case let .on_off(modify) = array[section][0]{
            if (modify.ison ?? false) == false{ return nil}
            let view = UIView()
            view.backgroundColor = .clear
            return view
        }
        return nil
    }
}
//MARK: - 通知
extension QCAboutViewController{
    override func addNotify() {
        super.addNotify()
        NotifyTool.add(self, #selector(initData), updateVersion)
        addNotifyForBin()
        addNotifyForFulikun()
    }
}






